;;; GNU Guix --- Functional package management for GNU
;;;
;;; Copyright © 2022 (unmatched parenthesis <paren@disroot.org>
;;;
;;; This file is not part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (guixrus packages helix)
  #:use-module (guix build-system cargo)
  #:use-module (guix gexp)
  #:use-module (guix git-download)
  #:use-module ((guix licenses) #:prefix license:)
  #:use-module (guix packages)
  #:use-module (gnu packages crates-io)
  #:use-module ((guixrus packages common rust) #:prefix rus:)
  #:use-module ((guixrus packages tree-sitter) #:prefix rus:)
  #:use-module ((guixrus contributors) #:prefix contributor:))

;;; XXX This package pulls in unauditable blobs; namely, the generated Tree-sitter C
;;; programs. This should be fixable by adding the tree-sitter grammars themselves to
;;; Guix and copying the output files into Helix's runtime directory.
(define-public helix
  (let ((commit "d11b6521399f41cb4c0b75ebaa5770972f550ebb")
        (revision "0"))
    (package
     (name "helix")
     (version (git-version "0.6.0" revision commit))
     (source (origin
               (method git-fetch)
               (uri (git-reference
                     (commit commit)
                     (url "https://github.com/helix-editor/helix")
                     ;; Helix pulls in Tree-sitter grammars in its submodules.
                     (recursive? #t)))
               (modules '((guix build utils)))
               (snippet
                #~(delete-file-recursively
                   "helix-syntax/languages/tree-sitter-yaml/yaml-test-suite"))
               (sha256
                (base32
                 "1xpa8zf7abwri6wyxb90nvqi3sqjkvmy7dllxairv07x6csrvsgi"))))
     (build-system cargo-build-system)
     (arguments
      (list ;; XXX tests fail
            #:tests? #f
            #:cargo-inputs
            `(("rust-anyhow" ,rust-anyhow-1)
              ("rust-arc-swap" ,rust-arc-swap-1)
              ("rust-autocfg" ,rust-autocfg-1)
              ("rust-bitflags" ,rust-bitflags-1)
              ("rust-cassowary" ,rust-cassowary-0.3)
              ("rust-cc" ,rust-cc-1)
              ("rust-chardetng" ,rus:rust-chardetng-0.1)
              ("rust-chrono" ,rust-chrono-0.4)
              ("rust-clipboard-win" ,rus:rust-clipboard-win-4)
              ("rust-content-inspector"
               ,rust-content-inspector-0.2)
              ("rust-crossterm" ,rus:rust-crossterm-0.23)
              ("rust-encoding" ,rust-encoding-rs-0.8)
              ("rust-etcetera" ,rus:rust-etcetera-0.3)
              ("rust-futures-executor"
               ,rust-futures-executor-0.3)
              ("rust-futures-util" ,rust-futures-util-0.3)
              ("rust-fuzzy-matcher" ,rust-fuzzy-matcher-0.3)
              ("rust-grep-regex" ,rust-grep-regex-0.1)
              ("rust-grep-searcher" ,rust-grep-searcher-0.1)
              ("rust-ignore" ,rust-ignore-0.4)
              ("rust-jsonrpc-core" ,rus:rust-jsonrpc-core-18)
              ("rust-libloading" ,rust-libloading-0.7)
              ("rust-log" ,rust-log-0.4)
              ("rust-lsp-types" ,rus:rust-lsp-types-0.92)
              ("rust-num-cpus" ,rust-num-cpus-1)
              ("rust-once-cell" ,rust-once-cell-1)
              ("rust-pulldown-cmark" ,rus:rust-pulldown-cmark-0.9)
              ("rust-regex" ,rust-regex-1)
              ("rust-ropey" ,rus:rust-ropey-1)
              ("rust-serde" ,rust-serde-1)
              ("rust-serde-json" ,rust-serde-json-1)
              ("rust-signal-hook" ,rust-signal-hook-0.3)
              ("rust-signal-hook-tokio"
               ,rus:rust-signal-hook-tokio-0.3)
              ("rust-similar" ,rust-similar-2)
              ("rust-slotmap" ,rus:rust-slotmap-1)
              ("rust-smallvec" ,rust-smallvec-1)
              ("rust-smartstring" ,rust-smartstring-0.2)
              ("rust-thiserror" ,rust-thiserror-1)
              ("rust-threadpool" ,rust-threadpool-1)
              ("rust-tokio" ,rust-tokio-1)
              ("rust-tokio-stream" ,rus:rust-tokio-stream-0.1)
              ("rust-toml" ,rust-toml-0.5)
              ("rust-tree-sitter" ,rus:rust-tree-sitter-0.20)
              ("rust-unicode-general-category"
               ,rus:rust-unicode-general-category-0.5)
              ("rust-unicode-segmentation"
               ,rus:rust-unicode-segmentation-1)
              ("rust-unicode-width" ,rust-unicode-width-0.1)
              ("rust-url" ,rust-url-2)
              ("rust-which" ,rust-which-4))
            #:cargo-development-inputs
            `(("rust-fern" ,rust-fern-0.6)
              ("rust-quickcheck" ,rust-quickcheck-1))
            #:phases
            #~(modify-phases %standard-phases
                (replace 'install
                  (lambda _
                    (install-file "target/release/hx"
                                  (string-append #$output "/bin"))))
                (add-before 'package 'patch-Cargo.tomls
                  (lambda _
                    (substitute* (list "helix-dap/Cargo.toml"
                                       "helix-lsp/Cargo.toml"
                                       "helix-syntax/Cargo.toml"
                                       "helix-term/Cargo.toml"
                                       "helix-tui/Cargo.toml"
                                       "helix-view/Cargo.toml"
                                       "xtask/Cargo.toml")
                      (("^helix-.* = .*$") ""))
                    (substitute* "helix-term/Cargo.toml"
                      (("^tui = .*$") ""))))
                (add-after 'install 'install-runtime
                  (lambda _
                    (copy-recursively "runtime"
                                      (string-append
                                       #$output
                                       "/usr/share/helix/runtime"))))
                (add-after 'install-runtime 'patch-runtime-env-var
                  (lambda _
                    (wrap-program (string-append #$output "/bin/hx")
                      `("HELIX_RUNTIME" =
                        (,(string-append
                           #$output
                           "/usr/share/helix/runtime")))))))))
     (home-page "https://helix-editor.com")
     (synopsis "The post-modern text editor")
     (description
      "Helix is a modal terminal-based text editor inspired by
Neovim and Kakoune, with modern features like an LSP client
included by default.")
     (license license:mpl2.0)
     (properties `((maintainers . (,contributor:unmatched-paren)))))))
